/*
 * File:	ElftosbLexer.h
 *
 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
 * See included license file for license details.
 */

// This header just wraps the standard flex C++ header to make it easier to include
// without having to worry about redefinitions of the class name every time.

#if !defined(_ElftosbLexer_h_)
#define _ElftosbLexer_h_

#include "ElftosbAST.h"
#include "FlexLexer.h"
#include "elftosb_parser.tab.hpp"
#include <vector>
#include <string>
#include <stdexcept>
#include "Blob.h"

using namespace std;

namespace elftosb
{

/*!
 * \brief Exception class for syntax errors.
 */
class syntax_error : public std::runtime_error
{
public:
	explicit syntax_error(const std::string & __arg) : std::runtime_error(__arg) {}
};

/*!
 * \brief Exception class for lexical errors.
 */
class lexical_error : public std::runtime_error
{
public:
	explicit lexical_error(const std::string & __arg) : std::runtime_error(__arg) {}
};

/*!
 * \brief Lexical scanner class for elftosb command files.
 *
 * This class is a subclass of the standard C++ lexer class produced by
 * Flex. It's primary purpose is to provide a clean way to report values
 * for symbols, without using the yylval global. This is necessary because
 * the parser produced by Bison is a "pure" parser.
 *
 * In addition, this class manages a list of source names generated by
 * parsing. The lexer uses this list to determine if an identifier is
 * a source name or a constant identifier.
 */
class ElftosbLexer : public yyFlexLexer
{
public:
	//! \brief Constructor.
	ElftosbLexer(istream & inputStream);

	//! \brief Lexer interface. Returns one token.
	virtual int yylex();
	
	//! \brief Returns the value for the most recently produced token in \a value.
	virtual void getSymbolValue(YYSTYPE * value);
	
	//! \brief Returns the current token's location in \a loc.
	inline token_loc_t & getLocation() { return m_location; }
	
	//! \name Source names
	//@{
	void addSourceName(std::string * ident);
	bool isSourceName(std::string * ident);
	//@}

protected:
	YYSTYPE m_symbolValue;	//!< Value for the current token.
	int m_line;	//!< Current line number.
	token_loc_t m_location;	//!< Location for the current token.
	Blob * m_blob;	//!< The binary object value as its being constructed.
	int m_blobFirstLine;	//!< Line number for the first character of a blob.

	typedef std::vector<std::string> string_vector_t;
	string_vector_t m_sources;	//!< Vector of source identifiers;
	
	//! \brief Throw an elftosb::lexical_error exception.
	virtual void LexerError(const char * msg);

	//! \brief Process a string containing escape sequences.
	int processStringEscapes(const char * in, char * out);
};

}; // namespace elftosb

#endif // _ElftosbLexer_h_
